<!DOCTYPE html>



  


<html class="theme-next gemini use-motion" lang="cn">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />






















<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=6.0.0" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=6.0.0">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=6.0.0">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=6.0.0">


  <link rel="mask-icon" href="/images/logo.svg?v=6.0.0" color="#222">





  <meta name="keywords" content="Hexo, NexT" />










<meta property="og:type" content="website">
<meta property="og:title" content="categories">
<meta property="og:url" content="http://yoursite.com/categories/index.html">
<meta property="og:site_name" content="hill&#39;s blog">
<meta property="og:locale" content="cn">
<meta property="article:published_time" content="2017-07-10T08:36:26.000Z">
<meta property="article:modified_time" content="2021-02-25T04:04:48.836Z">
<meta property="article:author" content="heyaojia">
<meta name="twitter:card" content="summary">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Gemini',
    version: '6.0.0',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":true,"scrollpercent":false,"onmobile":false},
    fancybox: false,
    fastclick: false,
    lazyload: false,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: 'Author'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://yoursite.com/categories/"/>





  <title>Erlang热更新原理 | hill's blog</title>
  








<meta name="generator" content="Hexo 4.2.1"></head>

<body itemscope itemtype="http://schema.org/WebPage" lang="cn">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"> <div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">hill's blog</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            Home
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-question-circle"></i> <br />
            
            Archives
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            Categories
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2021/02/25/Erlang/erlang_hotload/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="heyaojia">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="hill's blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">Erlang热更新原理</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">Posted on</span>
              
              <time title="Post created" itemprop="dateCreated datePublished" datetime="2021-02-25T12:04:48+08:00">2021-02-25</time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">In</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Erlang/" itemprop="url" rel="index">
                    <span itemprop="name">Erlang</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <h4 id="Erlang热更新原理"><a href="#Erlang热更新原理" class="headerlink" title="Erlang热更新原理"></a>Erlang热更新原理</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">前言 实践是检验的结果</span><br></pre></td></tr></table></figure>
<hr>
<p>env</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">erl OTP 19</span><br><span class="line">vmware linux centos7</span><br></pre></td></tr></table></figure>
<a id="more"></a>
<h4 id="一、热更新原理"><a href="#一、热更新原理" class="headerlink" title="一、热更新原理"></a>一、热更新原理</h4><h5 id="1、热更新原理"><a href="#1、热更新原理" class="headerlink" title="1、热更新原理"></a>1、热更新原理</h5><p>&emsp;官方文档是这样写道：<br>Erlang supports change of code in a running system. Code replacement is done on module level.（Erlang支持在运行中的系统的代码修改，代码替换是在模块级别上完成的） </p>
<p>The code of a module can exist in two variants in a system: current and old. When a module is loaded into the system for the first time, the code becomes ‘current’. If then a new instance of the module is loaded, the code of the previous instance becomes ‘old’ and the new instance becomes ‘current’.（意思是维护了两套代码，new and old，代码使用的是current）</p>
<ul>
<li>这里是name为t2的原因，首次编写的时候是一个gen_server，发现pid没有变化</li>
<li>所以又写了个t2来测试，gen_server热更新下面讲<br><img src="https://note.youdao.com/yws/api/personal/file/DD4CB519A1D1448AA49CAE0B3C18F897?method=download&shareKey=63ce79565994d2ae96c5f5f335b220e0" alt="实现的热更新代码">  <h5 id="热更时实际调用"><a href="#热更时实际调用" class="headerlink" title="* 热更时实际调用"></a>* 热更时实际调用</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">-module(t2).</span><br><span class="line">-export([loop&#x2F;0]).</span><br><span class="line"></span><br><span class="line">loop() -&gt;</span><br><span class="line">    receive</span><br><span class="line">        code_switch -&gt;</span><br><span class="line">            t2:loop();</span><br><span class="line">        Msg -&gt;</span><br><span class="line">            ...</span><br><span class="line">            loop()</span><br><span class="line">    end.</span><br></pre></td></tr></table></figure>
<img src="https://img-blog.csdn.net/20141116235840361?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbXljd3E=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/NorthEast" alt=""><br>需要一张图来解释一下，外部m：loop 和模块内loop的区别,内部调用不会加载模块代码，外部调用函数，会先加载模块代码再执行，外部调用的开销比内部调用的大，所以在写代码的时候，不要在内部用外部调用。  </li>
</ul>
<p>引用没有开花的树：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">1.外部调用的开销比本地调用大一点。外部调用时通过指针找到这个模块函数的导出地址，当模块热更时，就会修改这个指针指向的地址。内部调用是上下文跳转，对比少了一个指针查找，外加原子锁的开销。</span><br><span class="line"></span><br><span class="line">2.外部调用的函数代码加载的时间稍微长一点，需要获取外部函数在导出函数表的地址，避免在执行时才去导出函数表查找函数地址造成开销。</span><br></pre></td></tr></table></figure>

<h5 id="发现的问题"><a href="#发现的问题" class="headerlink" title="*发现的问题"></a>*发现的问题</h5><ol>
<li>Gen_server在hot code loading的时候没有被kill掉，是怎么一回事？</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">%%@gen_sever start_link callback</span><br><span class="line">init([]) -&gt;</span><br><span class="line">    io:format(&quot;i am init ~p&quot;,[self()]),</span><br><span class="line">    &#123;ok, #t_state&#123;&#125;, 10000&#125;.</span><br><span class="line"></span><br><span class="line">l() -&gt;</span><br><span class="line">    compile:file(t),</span><br><span class="line">    code:purge(t),</span><br><span class="line">    code:load_file(t),</span><br></pre></td></tr></table></figure>
<p>设置了一个超时gen_server,这时查看gen_server进程正在进行调用的函数<br><img src="https://note.youdao.com/yws/api/personal/file/75636E06422940DFA55099119AD9E572?method=download&shareKey=781fd2d5ca6eb5870ca01d3fe843ada9" alt=""><br><img src="https://note.youdao.com/yws/api/personal/file/5FDEE7E7D10946B882D41BB04FEBC086?method=download&shareKey=6f32c71b7e5aee81420d6ab24aee83e9" alt=""></p>
<p>不同在于在代码的版本切换中，在官方文档中发现道：  </p>
<p>&emsp;If a third instance of the module is loaded, the code server removes (purges) the old code and any processes lingering in it is terminated. Then the third instance becomes ‘current’ and the previously current code becomes ‘old’.<br>（假设模块的第三个实例被加载，code_server移除（使纯净）旧代码和调用他的进程，第三个实例将会变成’current’之前的实例（第二次加载）将会变成old）</p>
<p>&emsp;结合这个问题，由于t2例子是阻塞在loop/0里面，当第一次调用loadfile的时候，远本阻塞的函数继续使用old代码，而新调用loop函数的代码将会使用新代码，当第二次使用loadfile的时候，purge将会把初始化的那一套代码给delete掉，就并且kill掉使用旧代码的进程，而实现的gen_server，阻塞在gen_serverloop中，都是在gen调用t的代码，所以没有kill掉进程<br><img src="https://note.youdao.com/yws/api/personal/file/78F6B7A6D6FC4E24A936A77942E9275C?method=download&shareKey=1a4bc0f333720e4f1702513ccc1cbf94" alt=""></p>
<h5 id="2、热更新code-server源码阅读"><a href="#2、热更新code-server源码阅读" class="headerlink" title="2、热更新code_server源码阅读"></a>2、热更新code_server源码阅读</h5><p>&emsp;阅读code：load_file后，发现是code_server在做事<br>&emsp;code server是OTP框架的，有两种模式interactive（主动） or embedded（手动），在启动的时候通过参数修改</p>
<figure class="highlight erl"><figcaption><span>-mode xxx```  </span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">为了防止修改kernel、stadlib、compiler的代码，给这些模块的代码设置了sticky的状态，可以在命令行用-nostick修改</span><br><span class="line"></span><br><span class="line">走到最后调用了erlang：module_loaded/<span class="number">1</span> （BIF函数）</span><br><span class="line"></span><br><span class="line">#### 二、参考项目热更新工具</span><br><span class="line">编译 -&gt; 上传 -&gt; erlang shell远程节点，封装cmd到arg中，执行处理函数，解析cmd，reload beam</span><br></pre></td></tr></table></figure>
<p>code:soft_purge(Module),<br>Ret = code:load_file(Module),<br>?INFO_MSG(“Module:<del>w, reload:</del>w”, [Module, Ret])</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">最终代码走向熟悉的code模块</span><br><span class="line">#### 三、自己实现一个热工新工具</span><br></pre></td></tr></table></figure>
<p>#!/usr/bin/bash</p>
<p>ERL=’/opt/erlang19.3/bin/erl’<br>TARGET=$1<br>PARAMS=” -setcookie hill -pa src/“<br>NODE=”hill_test”<br>TARGET_ERL=$2</p>
<p>help(){<br>    echo ‘使用说明’<br>    echo ‘基本语法:  功能指令 [option]’<br>    echo ‘命令模块：’<br>    echo “输入start 或者 update”<br>}</p>
<p>start(){<br>   echo “start erl”<br>   CMD=start<br>   RANDOM=$(date +%N)<br>   cd src/<br>   R= erlc *.erl<br>   cd ..<br>   ${ERL} -name ${NODE} $PARAMS -s t s<br>}</p>
<p>update(){<br>    echo ${TARGET_ERL}<br>    echo “update now”<br>    echo “compile now”<br>    cd src<br>    TARGET_ERL1=”${TARGET_ERL}.erl”<br>    echo ${TARGET_ERL1}<br>    erlc ${TARGET_ERL1}<br>    cd ../<br>    echo “compile ok”<br>    CMD=$1<br>    RANDOM=$(date +%N)<br>    ${ERL} -name command_${CMD}_${RANDOM} $PARAMS -s t l -extra ${NODE}<br>}</p>
<p>case ${TARGET} in<br>    update) update $*;;<br>    start) start;;<br>    *) custom_param ;;<br>esac</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">![](https:&#x2F;&#x2F;note.youdao.com&#x2F;yws&#x2F;api&#x2F;personal&#x2F;file&#x2F;862876B45F0842A2B5F42FED4D892104?method&#x3D;download&amp;shareKey&#x3D;3c1504f3df4cb6561c804d0e6d674f5c)</span><br><span class="line"></span><br><span class="line">#### 脑图总结</span><br><span class="line">还没开搞</span><br></pre></td></tr></table></figure>
<p><a href="">资源地址</a>(提取码: )<br><img src="" alt="脑图"></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">##### 需要深究的点（待补充）</span><br><span class="line">1. 能否看到代码调用时的版本时old还是current</span><br></pre></td></tr></table></figure>
<p>待补充</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">##### 我自己的学习资料</span><br></pre></td></tr></table></figure>
<p><a href="https://pan.baidu.com/s/1X7XqI3QDehabRvVEFzEWFQ" target="_blank" rel="noopener">https://pan.baidu.com/s/1X7XqI3QDehabRvVEFzEWFQ</a> </p>
<pre><code>
##### 拓展阅读
1. 底层热更新的实现
    [参考这篇博客](https://blog.csdn.net/mycwq/article/details/43372687)

##### 引用  
##### * [没有开花的树](https://blog.csdn.net/mycwq/article/details/41175237)
##### * [坚强2002的博客](https://www.cnblogs.com/me-sa/archive/2011/10/29/erlang0010.html)
##### * [官方文档](http://erlang.org/doc/reference_manual/code_loading.html)</code></pre><script type="text/javascript" src="https://cdn.jsdelivr.net/npm/kity@2.0.4/dist/kity.min.js"></script><script type="text/javascript" src="https://cdn.jsdelivr.net/npm/kityminder-core@1.4.50/dist/kityminder.core.min.js"></script><script defer="true" type="text/javascript" src="https://cdn.jsdelivr.net/npm/hexo-simple-mindmap@0.2.0/dist/mindmap.min.js"></script><link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/hexo-simple-mindmap@0.2.0/dist/mindmap.min.css">
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2021/02/25/Erlang/erlang_test/" rel="next" title="《Erlang Test》">
                <i class="fa fa-chevron-left"></i> 《Erlang Test》
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2021/02/25/Erlang/recon/" rel="prev" title="UAT环境的一次cpu占用过高">
                UAT环境的一次cpu占用过高 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            Table of Contents
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            Overview
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name">heyaojia</p>
              <p class="site-description motion-element" itemprop="description">游戏行业的一枚小鲜肉</p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives">
              
                  <span class="site-state-item-count">21</span>
                  <span class="site-state-item-name">posts</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/categories/index.html">
                  <span class="site-state-item-count">5</span>
                  <span class="site-state-item-name">categories</span>
                </a>
              </div>
            

            

          </nav>

          

          
            <div class="links-of-author motion-element">
                
                  <span class="links-of-author-item">
                    <a href="git@gitee.com:hillcool/hillcool.git" target="_blank" title="GitHub">
                      
                        <i class="fa fa-fw fa-gitee"></i>GitHub</a>
                  </span>
                
            </div>
          

          
          

          
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-4"><a class="nav-link" href="#Erlang热更新原理"><span class="nav-number">1.</span> <span class="nav-text">Erlang热更新原理</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#一、热更新原理"><span class="nav-number">2.</span> <span class="nav-text">一、热更新原理</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#1、热更新原理"><span class="nav-number">2.1.</span> <span class="nav-text">1、热更新原理</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#热更时实际调用"><span class="nav-number">2.2.</span> <span class="nav-text">* 热更时实际调用</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#发现的问题"><span class="nav-number">2.3.</span> <span class="nav-text">*发现的问题</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#2、热更新code-server源码阅读"><span class="nav-number">2.4.</span> <span class="nav-text">2、热更新code_server源码阅读</span></a></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      
        <div class="back-to-top">
          <i class="fa fa-arrow-up"></i>
          
        </div>
      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2021</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">heyaojia</span>

  

  
</div>









        







        
      </div>
    </footer>

    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>
























  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=6.0.0"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=6.0.0"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=6.0.0"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=6.0.0"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=6.0.0"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=6.0.0"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=6.0.0"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

</body>
</html>
